In [3]:
# -*- coding: utf-8 -*-
"""
单模式三波长测试 - 基于多模式多波长光场调制系统框架
"""

import torch
import numpy as np
import matplotlib.pyplot as plt
import os
import time
from datetime import datetime

# 导入自定义模块
from label_utils import create_evaluation_regions_mode_wavelength, evaluate_output, evaluate_all_regions, visualize_labels
from config import Config
from data_generator import MultiModeMultiWavelengthDataGenerator
from visualizer import Visualizer
from trainer import Trainer
from model import MultiModeMultiWavelengthModel
from simulator import Simulator

# 记录开始时间
start_time = time.time()

# 设置随机种子,确保结果可重现
torch.manual_seed(42)
np.random.seed(42)

print("=" * 60)
print("单模式三波长测试 - 基于多模式多波长框架")
print("=" * 60)

# ===== 掩码加载器类(内联定义)=====
class SimpleMaskLoader:
    """简化的相位掩码加载器"""
    
    def __init__(self, config):
        self.config = config
    
    def create_fallback_masks(self, num_layers=2):
        """创建备用聚焦掩码"""
        print("⚠ 创建备用聚焦掩码...")
        
        def create_focusing_mask(size, wavelength, focal_length, pixel_size):
            center = size // 2
            y, x = np.ogrid[:size, :size]
            r_squared = ((x - center) * pixel_size) ** 2 + ((y - center) * pixel_size) ** 2
            k = 2 * np.pi / wavelength
            phase = -k * r_squared / (2 * focal_length)
            return np.mod(phase, 2 * np.pi)
        
        masks = []
        focal_lengths = [50e-3, 100e-3, 150e-3]  # 三种不同层的焦距
        
        for layer_idx in range(num_layers):
            layer_masks = []
            for wl_idx, wavelength in enumerate(self.config.wavelengths):
                focal_length = focal_lengths[layer_idx % len(focal_lengths)]
                mask = create_focusing_mask(
                    self.config.layer_size, wavelength, focal_length, self.config.pixel_size
                )
                layer_masks.append(mask)
            masks.append(layer_masks)
        
        print(f"✓ 创建了 {len(masks)} 层备用掩码")
        return masks
    
    def get_masks_for_simulation(self, trained_masks=None, num_layers=2):
        """获取用于仿真的掩码"""
        if trained_masks is not None:
            print("✓ 使用训练好的相位掩码进行仿真")
            return trained_masks
        else:
            print("⚠ 使用备用掩码进行仿真")
            return self.create_fallback_masks(num_layers)

# 创建单模式三波长测试配置
config = Config(
    # 基本参数 - 修改为单模式三波长
    num_modes=1,                                          # 单模式
    wavelengths=np.array([450e-9, 550e-9, 650e-9]),      # 三波长:蓝光、绿光、红光
    
    # 空间参数
    field_size=50,                              # 场大小(像素)
    layer_size=200,                             # 层大小(像素)
    focus_radius=5,                             # 焦点半径(像素)
    detectsize=15,                              # 检测区域大小(像素)
    
    # 物理参数
    z_layers=40e-6,                             # 层间距离(m)
    z_prop=300e-6,                              # 传播距离(m)
    z_step=20e-6,                               # 传播步长(m)
    pixel_size=1e-6,                            # 像素大小(m)
    
    # 检测区域偏移 - 为每个波长定义不同的偏移(三个波长横向排列)
    offsets=[(0,0), (60,0), (120,0)],           # 三个波长的检测区域偏移
    
    # 训练参数 - 适当增加训练轮数以处理三波长的复杂性
    learning_rate=0.01,                         # 学习率
    lr_decay=0.99,                              # 学习率衰减
    epochs=600,                                 # 训练轮数(增加用于三波长)
    batch_size=1,                               # 批量大小(单模式)
    
    # 保存参数
    save_dir="./test_single_mode_tri_wavelength/",  # 测试保存目录
    flag_savemat=True                           # 是否保存.mat文件
)

print(f"测试配置:")
print(f"  模式数: {config.num_modes}")
print(f"  波长: {[f'{wl*1e9:.0f}nm' for wl in config.wavelengths]}")
print(f"  训练轮次: {config.epochs}")
print(f"  保存目录: {config.save_dir}")

# 确保保存目录存在
os.makedirs(config.save_dir, exist_ok=True)
os.makedirs(os.path.join(config.save_dir, "trained_models"), exist_ok=True)

# ===== 阶段1: 数据准备 =====
print("\n" + "="*50)
print("阶段1: 数据准备")
print("="*50)

# 创建数据生成器
print("创建数据生成器...")
data_generator = MultiModeMultiWavelengthDataGenerator(config)

# 生成单模式三波长标签
print("生成标签...")
labels = data_generator.generate_labels()

# 可视化标签布局
print("可视化标签布局...")
visualize_labels(labels, config.wavelengths)

# 创建评估区域
print("创建评估区域...")
evaluation_regions = create_evaluation_regions_mode_wavelength(
    config.layer_size, 
    config.layer_size, 
    config.focus_radius, 
    detectsize=config.detectsize
)

print("✓ 数据准备完成")

# ===== 阶段2: 模型训练 =====
print("\n" + "="*50)
print("阶段2: 模型训练")
print("="*50)

# 检查是否存在已训练的模型
trained_models_dir = os.path.join(config.save_dir, "trained_models")
existing_models = []
if os.path.exists(trained_models_dir):
    model_files = [f for f in os.listdir(trained_models_dir) if f.startswith("model_") and f.endswith("layers.pth")]
    existing_models = [f for f in model_files]

# 定义要训练的层数选项
num_layer_options = [1, 2, 3]

# 询问是否使用现有模型或重新训练
use_existing = False
if existing_models:
    print(f"发现已存在的训练模型: {existing_models}")
    try:
        response = input("是否使用现有模型?(y/n,默认n): ").lower().strip()
        use_existing = response == 'y'
    except:
        print("使用默认选项:重新训练")
        use_existing = False

if use_existing and existing_models:
    print("加载现有训练模型...")
    results = {'models': [], 'losses': [], 'phase_masks': [], 'weights_pred': [], 'visibility': []}
    
    for num_layers in num_layer_options:
        model_path = os.path.join(trained_models_dir, f"model_{num_layers}layers.pth")
        if os.path.exists(model_path):
            print(f"加载 {num_layers} 层模型...")
            
            try:
                # 加载模型检查点
                checkpoint = torch.load(model_path, map_location='cpu')
                
                # 创建模型实例
                model = MultiModeMultiWavelengthModel(config, num_layers)
                model.load_state_dict(checkpoint['model_state_dict'])
                
                # 提取相位掩码
                phase_masks = []
                if hasattr(model, 'get_phase_masks_for_simulation'):
                    phase_masks = model.get_phase_masks_for_simulation()
                else:
                    # 兼容旧版本
                    for layer in model.layers:
                        phase = layer.phase.detach().cpu().numpy()
                        phase = phase % (2 * np.pi)
                        wavelength_masks = []
                        for _ in range(len(config.wavelengths)):
                            wavelength_masks.append(phase)
                        phase_masks.append(wavelength_masks)
                
                # 获取训练损失和可见度
                losses = checkpoint.get('train_losses', [])
                visibility = checkpoint.get('visibility', [])
                
                # 如果没有可见度数据,需要重新评估
                if not visibility:
                    print(f"  重新评估 {num_layers} 层模型...")
                    trainer_temp = Trainer(config, data_generator, MultiModeMultiWavelengthModel, evaluation_regions=evaluation_regions)
                    test_loader = trainer_temp._create_data_loaders()[1]
                    eval_results = trainer_temp._evaluate_model(model, test_loader)
                    visibility = eval_results['visibility']
                    weights_pred = eval_results['weights_pred']
                else:
                    weights_pred = []
                
                results['models'].append(model)
                results['losses'].append(losses)
                results['phase_masks'].append(phase_masks)
                results['weights_pred'].append(weights_pred)
                results['visibility'].append(visibility)
                
                print(f"✓ 成功加载 {num_layers} 层模型")
                
            except Exception as e:
                print(f"✗ 加载 {num_layers} 层模型失败: {e}")
                # 添加空结果以保持索引一致
                results['models'].append(None)
                results['losses'].append([])
                results['phase_masks'].append([])
                results['weights_pred'].append([])
                results['visibility'].append([])
        else:
            print(f"✗ 未找到 {num_layers} 层模型文件")
            # 添加空结果以保持索引一致
            results['models'].append(None)
            results['losses'].append([])
            results['phase_masks'].append([])
            results['weights_pred'].append([])
            results['visibility'].append([])
else:
    print("开始训练新模型...")
    
    # 创建训练器
    trainer = Trainer(config, data_generator, MultiModeMultiWavelengthModel, evaluation_regions=evaluation_regions)
    
    # 训练多个层数的模型
    results = trainer.train_multiple_models(num_layer_options)

print("✓ 模型准备完成")

# ===== 阶段3: 结果分析 =====
print("\n" + "="*50)
print("阶段3: 结果分析")
print("="*50)

# 检查可见度数据结构
print("检查训练结果...")
print(f"results键: {list(results.keys())}")
print(f"可见度数据结构: {len(results['visibility'])}层")

valid_results = []
for i, vis_data in enumerate(results['visibility']):
    if vis_data:  # 只处理非空的可见度数据
        expected_length = len(config.wavelengths) * config.num_modes
        print(f"第{i+1}层 ({num_layer_options[i]}层模型):")
        print(f"  数据长度: {len(vis_data)}")
        print(f"  期望长度: {expected_length} ({len(config.wavelengths)}波长 × {config.num_modes}模式)")
        
        if len(vis_data) == expected_length:
            print(f"  ✅ 数据长度匹配!")
            valid_results.append(i)
            # 按波长显示(单模式)
            vis_array = np.array(vis_data).reshape(len(config.wavelengths), config.num_modes)
            for wl_idx, wl in enumerate(config.wavelengths):
                wl_nm = wl * 1e9
                print(f"    {wl_nm:.0f}nm: 模式1={vis_array[wl_idx, 0]:.6f}")
        else:
            print(f"  ❌ 数据长度不匹配!")
    else:
        print(f"第{i+1}层 ({num_layer_options[i]}层模型): 无可见度数据")

# 可视化训练损失
if results['losses'] and any(results['losses']):
    print("可视化训练损失...")
    plt.figure(figsize=(10, 6))
    for i, num_layers in enumerate(num_layer_options):
        if results['losses'][i]:  # 确保有损失数据
            plt.plot(results['losses'][i], label=f'{num_layers} 层')
    plt.xlabel('训练轮次')
    plt.ylabel('损失值')
    plt.title('单模式三波长 - 不同层数模型的训练损失')
    plt.legend()
    plt.grid(True)
    plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
    plt.show()

# 可视化三波长可见度结果
if valid_results:
    print("可视化三波长可见度结果...")
    fig, axes = plt.subplots(1, len(config.wavelengths), figsize=(18, 5))
    if len(config.wavelengths) == 1:
        axes = [axes]

    wavelength_names = [f"{wl*1e9:.0f}nm" for wl in config.wavelengths]
    colors = ['blue', 'green', 'red']  # 蓝光、绿光、红光

    for wl_idx, (ax, wl_name, color) in enumerate(zip(axes, wavelength_names, colors)):
        # 提取每个波长下不同层数模型的可见度
        layer_visibilities = []
        valid_layer_options = []
        
        for layer_idx in valid_results:
            vis_data = results['visibility'][layer_idx]
            if len(vis_data) == len(config.wavelengths) * config.num_modes:
                vis_array = np.array(vis_data).reshape(len(config.wavelengths), config.num_modes)
                wl_vis = vis_array[wl_idx, 0]  # 单模式
                layer_visibilities.append(wl_vis)
                valid_layer_options.append(num_layer_options[layer_idx])
        
        if layer_visibilities:
            ax.plot(valid_layer_options, layer_visibilities, 
                    'o-', color=color, linewidth=2, markersize=8, label='单模式')
        
        ax.set_xlabel('层数')
        ax.set_ylabel('可见度')
        ax.set_title(f'{wl_name} 可见度')
        ax.legend()
        ax.grid(True)
        ax.set_ylim(0, 1)

    plt.suptitle('单模式三波长可见度对比', fontsize=16)
    plt.tight_layout()
    plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
    plt.show()

# 创建三波长综合对比图
if valid_results:
    print("创建三波长综合对比图...")
    plt.figure(figsize=(12, 8))
    
    # 上半部分:各波长随层数变化
    plt.subplot(2, 1, 1)
    colors = ['blue', 'green', 'red']
    wavelength_names = [f"{wl*1e9:.0f}nm" for wl in config.wavelengths]
    
    for wl_idx, (wl_name, color) in enumerate(zip(wavelength_names, colors)):
        layer_visibilities = []
        valid_layer_options = []
        
        for layer_idx in valid_results:
            vis_data = results['visibility'][layer_idx]
            if len(vis_data) == len(config.wavelengths) * config.num_modes:
                vis_array = np.array(vis_data).reshape(len(config.wavelengths), config.num_modes)
                wl_vis = vis_array[wl_idx, 0]  # 单模式
                layer_visibilities.append(wl_vis)
                valid_layer_options.append(num_layer_options[layer_idx])
        
        if layer_visibilities:
            plt.plot(valid_layer_options, layer_visibilities, 
                    'o-', color=color, linewidth=2, markersize=8, label=wl_name)
    
    plt.xlabel('层数')
    plt.ylabel('可见度')
    plt.title('三波长可见度随层数变化')
    plt.legend()
    plt.grid(True)
    plt.ylim(0, 1)
    
    # 下半部分:各层数的波长对比
    plt.subplot(2, 1, 2)
    bar_width = 0.25
    x_pos = np.arange(len(valid_results))
    
    for wl_idx, (wl_name, color) in enumerate(zip(wavelength_names, colors)):
        wl_visibilities = []
        
        for layer_idx in valid_results:
            vis_data = results['visibility'][layer_idx]
            vis_array = np.array(vis_data).reshape(len(config.wavelengths), config.num_modes)
            wl_vis = vis_array[wl_idx, 0]  # 单模式
            wl_visibilities.append(wl_vis)
        
        plt.bar(x_pos + wl_idx * bar_width, wl_visibilities, 
                bar_width, label=wl_name, color=color, alpha=0.7)
    
    plt.xlabel('模型层数')
    plt.ylabel('可见度')
    plt.title('不同层数模型的三波长可见度对比')
    plt.xticks(x_pos + bar_width, [f'{num_layer_options[i]}层' for i in valid_results])
    plt.legend()
    plt.grid(True, alpha=0.3)
    plt.ylim(0, 1)
    
    plt.tight_layout()
    plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
    plt.show()

# 创建可视化器并生成详细分析
if valid_results:
    print("创建详细可视化分析...")
    try:
        visualizer = Visualizer(config)
        
        # 组织数据
        visibility_by_mode = visualizer.organize_visibility_by_mode(results, config, num_layer_options)
        
        # 绘制图表
        visualizer.plot_visibility_by_mode(visibility_by_mode, num_layer_options, 
                                           save_path=f"{config.save_dir}/visibility_by_mode.png")
        
        visualizer.plot_visibility_comparison_by_mode_wavelength(visibility_by_mode, num_layer_options,
                                                                save_path=f"{config.save_dir}/visibility_matrix.png")
        
        # 打印摘要和保存数据
        visualizer.print_visibility_summary(visibility_by_mode, num_layer_options)
        visualizer.save_visibility_data(visibility_by_mode, num_layer_options, f"{config.save_dir}/visibility_data.csv")
    except Exception as e:
        print(f"可视化分析出错: {e}")

print("✓ 结果分析完成")

# ===== 阶段4: 光场传播仿真(所有模型)=====
print("\n" + "="*50)
print("阶段4: 光场传播仿真(所有模型)")
print("="*50)

# 获取所有有效模型
print("获取所有有效模型...")
valid_models = [(i, results['models'][i], results['visibility'][i], num_layer_options[i]) 
                for i in range(len(results['models'])) 
                if results['models'][i] is not None and results['visibility'][i]]

if valid_models:
    print(f"发现 {len(valid_models)} 个有效模型,将分别进行传播仿真")
    
    # 创建简化的掩码加载器
    print("准备仿真掩码...")
    mask_loader = SimpleMaskLoader(config)
    
    # 生成输入场(所有模型使用相同的输入场)
    print("生成输入场...")
    input_field = data_generator.generate_input_data()
    
    # 为每个有效模型进行仿真
    for model_idx, (idx, model, visibility, num_layers) in enumerate(valid_models):
        print(f"\n--- 处理第 {model_idx+1}/{len(valid_models)} 个模型: {num_layers}层 ---")
        print(f"平均可见度: {np.mean(visibility):.4f}")
        
        # 显示各波长的可见度
        vis_array = np.array(visibility).reshape(len(config.wavelengths), config.num_modes)
        for wl_idx, wavelength in enumerate(config.wavelengths):
            wl_nm = wavelength * 1e9
            print(f"  {wl_nm:.0f}nm: {vis_array[wl_idx, 0]:.4f}")
        
        # 获取该模型的相位掩码
        phase_masks = results['phase_masks'][idx]
        
        # 获取仿真掩码
        simulation_masks = mask_loader.get_masks_for_simulation(
            trained_masks=phase_masks, 
            num_layers=num_layers
        )
        
        try:
            # 创建模拟器
            print(f"创建 {num_layers} 层模型的模拟器...")
            simulator = Simulator(config, evaluation_regions=evaluation_regions)
            
            # 为单模式生成专用相位掩膜
            print(f"为 {num_layers} 层模型生成专用相位掩膜...")
            mode_specific_masks = simulator.generate_mode_specific_masks(simulation_masks, config.num_modes)
            
            # 模拟光场传播
            print(f"模拟 {num_layers} 层模型的光场传播...")
            simulator.simulate_propagation(
                simulation_masks, 
                input_field, 
                process_all_modes=True,
                mode_specific_masks=mode_specific_masks
            )
            
            # 打印相位掩膜信息
            print(f"保存 {num_layers} 层模型的相位掩膜信息...")
            if hasattr(model, 'print_phase_masks'):
                # 为每个模型创建单独的保存目录
                model_save_dir = os.path.join(config.save_dir, f"{num_layers}layer_model")
                os.makedirs(model_save_dir, exist_ok=True)
                model.print_phase_masks(save_path=model_save_dir)
            
            print(f"✓ {num_layers} 层模型仿真完成")
            
        except Exception as e:
            print(f"❌ {num_layers} 层模型仿真过程出错: {e}")
            print("继续处理下一个模型...")
            continue
    
    # 生成所有模型的性能对比总结
    print("\n--- 所有模型仿真结果总结 ---")
    print("模型性能对比:")
    
    for model_idx, (idx, model, visibility, num_layers) in enumerate(valid_models):
        avg_visibility = np.mean(visibility)
        print(f"  {num_layers}层模型: 平均可见度 = {avg_visibility:.4f}")
        
        # 显示各波长的详细可见度(单模式)
        vis_array = np.array(visibility).reshape(len(config.wavelengths), config.num_modes)
        for wl_idx, wavelength in enumerate(config.wavelengths):
            wl_nm = wavelength * 1e9
            print(f"    {wl_nm:.0f}nm: {vis_array[wl_idx, 0]:.4f}")
    
    # 找出最佳模型
    best_model_info = max(valid_models, key=lambda x: np.mean(x[2]))
    best_idx, best_model, best_visibility, best_num_layers = best_model_info
    
    print(f"\n🏆 最佳模型: {best_num_layers}层")
    print(f"   平均可见度: {np.mean(best_visibility):.4f}")
    
    # 显示最佳模型各波长的可见度
    vis_array = np.array(best_visibility).reshape(len(config.wavelengths), config.num_modes)
    for wl_idx, wavelength in enumerate(config.wavelengths):
        wl_nm = wavelength * 1e9
        print(f"   {wl_nm:.0f}nm: {vis_array[wl_idx, 0]:.4f}")
    
    # 分析三波长的性能平衡
    print(f"\n📊 三波长性能分析:")
    wl_names = [f"{wl*1e9:.0f}nm" for wl in config.wavelengths]
    best_vis_array = np.array(best_visibility).reshape(len(config.wavelengths), config.num_modes)
    
    max_vis = np.max(best_vis_array[:, 0])
    min_vis = np.min(best_vis_array[:, 0])
    std_vis = np.std(best_vis_array[:, 0])
    
    print(f"   最高可见度: {max_vis:.4f} ({wl_names[np.argmax(best_vis_array[:, 0])]})")
    print(f"   最低可见度: {min_vis:.4f} ({wl_names[np.argmin(best_vis_array[:, 0])]})")
    print(f"   标准差: {std_vis:.4f}")
    print(f"   平衡度: {1 - std_vis:.4f} (越接近1越平衡)")
    
    print(f"\n✅ 所有 {len(valid_models)} 个模型的仿真完成")
    
else:
    print("❌ 没有有效的训练结果,跳过仿真")

print("✓ 光场传播仿真阶段完成")

# ===== 阶段5: 保存最终结果 =====
print("\n" + "="*50)
print("阶段5: 保存最终结果")
print("="*50)

# 保存完整结果
print("保存完整结果...")
timestamp = datetime.now().strftime("%Y%m%d_%H%M")

# 准备保存数据
save_data = {
    'config': config.__dict__,  # 保存配置字典
    'models_state_dict': [model.state_dict() if model else {} for model in results['models']],
    'losses': results['losses'],
    'visibility': results['visibility'],
    'num_layer_options': num_layer_options,
    'timestamp': timestamp,
    'training_completed': True,
    'test_type': 'single_mode_tri_wavelength'
}

# 如果有最佳模型,添加最佳模型信息
if 'best_idx' in locals():
    save_data.update({
        'best_model_idx': best_idx,
        'best_num_layers': best_num_layers,
        'best_avg_visibility': np.mean(best_visibility) if best_visibility else 0,
        'wavelength_balance_std': np.std(np.array(best_visibility).reshape(len(config.wavelengths), config.num_modes)[:, 0])
    })

# 保存主结果文件
main_results_path = f"{config.save_dir}/complete_results_{timestamp}.pth"
torch.save(save_data, main_results_path)
print(f"✓ 主结果已保存: {main_results_path}")

# 保存单独的模型文件(便于后续加载)
for i, (model, num_layers) in enumerate(zip(results['models'], num_layer_options)):
    if model is not None:
        model_save_path = os.path.join(config.save_dir, "trained_models", f"model_{num_layers}layers.pth")
        torch.save({
            'model_state_dict': model.state_dict(),
            'model_config': {
                'num_layers': num_layers,
                'model_class': 'MultiModeMultiWavelengthModel'
            },
            'train_losses': results['losses'][i] if i < len(results['losses']) else [],
            'visibility': results['visibility'][i] if i < len(results['visibility']) else [],
            'config': config.__dict__,
            'timestamp': timestamp,
            'test_type': 'single_mode_tri_wavelength'
        }, model_save_path)
        print(f"✓ {num_layers}层模型已保存: {model_save_path}")

# 保存三波长性能分析报告
if 'best_idx' in locals():
    print("生成三波长性能分析报告...")
    
    report_path = f"{config.save_dir}/tri_wavelength_analysis_report.txt"
    with open(report_path, 'w', encoding='utf-8') as f:
        f.write("=" * 60 + "\n")
        f.write("单模式三波长光场调制系统性能分析报告\n")
        f.write("=" * 60 + "\n\n")
        
        f.write(f"测试时间: {timestamp}\n")
        f.write(f"测试类型: 单模式三波长\n")
        f.write(f"波长配置: {[f'{wl*1e9:.0f}nm' for wl in config.wavelengths]}\n")
        f.write(f"训练轮次: {config.epochs}\n")
        f.write(f"测试层数: {num_layer_options}\n\n")
        
        f.write("=" * 40 + "\n")
        f.write("所有模型性能对比\n")
        f.write("=" * 40 + "\n")
        
        for model_idx, (idx, model, visibility, num_layers) in enumerate(valid_models):
            avg_visibility = np.mean(visibility)
            f.write(f"\n{num_layers}层模型:\n")
            f.write(f"  平均可见度: {avg_visibility:.6f}\n")
            
            # 各波长详细可见度
            vis_array = np.array(visibility).reshape(len(config.wavelengths), config.num_modes)
            for wl_idx, wavelength in enumerate(config.wavelengths):
                wl_nm = wavelength * 1e9
                f.write(f"  {wl_nm:.0f}nm: {vis_array[wl_idx, 0]:.6f}\n")
            
            # 波长间平衡性分析
            wl_vis = vis_array[:, 0]
            f.write(f"  波长平衡性 (标准差): {np.std(wl_vis):.6f}\n")
            f.write(f"  最大-最小差值: {np.max(wl_vis) - np.min(wl_vis):.6f}\n")
        
        f.write("\n" + "=" * 40 + "\n")
        f.write("最佳模型详细分析\n")
        f.write("=" * 40 + "\n")
        
        f.write(f"\n最佳模型: {best_num_layers}层\n")
        f.write(f"平均可见度: {np.mean(best_visibility):.6f}\n\n")
        
        # 最佳模型各波长分析
        best_vis_array = np.array(best_visibility).reshape(len(config.wavelengths), config.num_modes)
        wl_names = [f"{wl*1e9:.0f}nm" for wl in config.wavelengths]
        
        f.write("各波长性能:\n")
        for wl_idx, (wavelength, wl_name) in enumerate(zip(config.wavelengths, wl_names)):
            vis_val = best_vis_array[wl_idx, 0]
            f.write(f"  {wl_name}: {vis_val:.6f}\n")
        
        f.write("\n三波长平衡性分析:\n")
        wl_vis_values = best_vis_array[:, 0]
        f.write(f"  最高可见度: {np.max(wl_vis_values):.6f} ({wl_names[np.argmax(wl_vis_values)]})\n")
        f.write(f"  最低可见度: {np.min(wl_vis_values):.6f} ({wl_names[np.argmin(wl_vis_values)]})\n")
        f.write(f"  标准差: {np.std(wl_vis_values):.6f}\n")
        f.write(f"  变异系数: {np.std(wl_vis_values)/np.mean(wl_vis_values):.6f}\n")
        f.write(f"  平衡度评分: {1 - np.std(wl_vis_values):.6f} (0-1,越高越平衡)\n")
        
        # 波长间相对性能
        f.write("\n波长相对性能 (以最高为基准):\n")
        max_vis = np.max(wl_vis_values)
        for wl_idx, wl_name in enumerate(wl_names):
            relative_perf = wl_vis_values[wl_idx] / max_vis
            f.write(f"  {wl_name}: {relative_perf:.3f} ({relative_perf*100:.1f}%)\n")
        
        f.write("\n" + "=" * 40 + "\n")
        f.write("技术参数总结\n")
        f.write("=" * 40 + "\n")
        
        f.write(f"\n空间参数:\n")
        f.write(f"  场大小: {config.field_size} 像素\n")
        f.write(f"  层大小: {config.layer_size} 像素\n")
        f.write(f"  像素大小: {config.pixel_size*1e6:.1f} μm\n")
        f.write(f"  焦点半径: {config.focus_radius} 像素\n")
        
        f.write(f"\n物理参数:\n")
        f.write(f"  层间距离: {config.z_layers*1e6:.1f} μm\n")
        f.write(f"  传播距离: {config.z_prop*1e6:.1f} μm\n")
        f.write(f"  传播步长: {config.z_step*1e6:.1f} μm\n")
        
        f.write(f"\n训练参数:\n")
        f.write(f"  学习率: {config.learning_rate}\n")
        f.write(f"  学习率衰减: {config.lr_decay}\n")
        f.write(f"  训练轮次: {config.epochs}\n")
        f.write(f"  批量大小: {config.batch_size}\n")
        
        f.write(f"\n检测区域配置:\n")
        for i, (offset, wl_name) in enumerate(zip(config.offsets, wl_names)):
            f.write(f"  {wl_name}: 偏移 {offset}\n")
    
    print(f"✓ 三波长分析报告已保存: {report_path}")

print("✓ 所有结果保存完成")

# ===== 程序完成 =====
print("\n" + "="*60)
print("单模式三波长测试完成!")
print("="*60)

# 计算总执行时间
total_end_time = time.time()
total_time = total_end_time - start_time
print(f"总执行时间: {total_time:.2f} 秒 ({total_time/60:.2f} 分钟)")

# 打印最终摘要
print("\n=== 测试执行摘要 ===")
print(f"测试类型: 单模式三波长")
print(f"模式数: {config.num_modes}")
print(f"波长: {[f'{wl*1e9:.0f}nm' for wl in config.wavelengths]}")
print(f"训练层数选项: {num_layer_options}")
print(f"训练轮次: {config.epochs}")
print(f"保存目录: {config.save_dir}")

if 'best_idx' in locals():
    print(f"\n🏆 最佳模型: {best_num_layers}层")
    print(f"平均可见度: {np.mean(best_visibility):.4f}")
    
    # 显示最佳模型各波长详细结果
    vis_array = np.array(best_visibility).reshape(len(config.wavelengths), config.num_modes)
    wl_names = [f"{wl*1e9:.0f}nm" for wl in config.wavelengths]
    
    print("各波长性能:")
    for wl_idx, wl_name in enumerate(wl_names):
        print(f"  {wl_name}: {vis_array[wl_idx, 0]:.4f}")
    
    # 三波长平衡性评估
    wl_vis_values = vis_array[:, 0]
    balance_score = 1 - np.std(wl_vis_values)
    print(f"\n📊 三波长平衡性:")
    print(f"  标准差: {np.std(wl_vis_values):.4f}")
    print(f"  平衡度评分: {balance_score:.4f} (0-1,越高越平衡)")
    
    # 性能等级评估
    avg_vis = np.mean(wl_vis_values)
    if avg_vis >= 0.8 and balance_score >= 0.8:
        performance_level = "优秀"
    elif avg_vis >= 0.6 and balance_score >= 0.6:
        performance_level = "良好"
    elif avg_vis >= 0.4 and balance_score >= 0.4:
        performance_level = "一般"
    else:
        performance_level = "需要改进"
    
    print(f"  综合性能等级: {performance_level}")

print(f"\n📁 主要输出文件:")
print(f"  完整结果: complete_results_{timestamp}.pth")
print(f"  分析报告: tri_wavelength_analysis_report.txt")
print(f"  可视化图表: tri_wavelength_*.png")
print(f"  训练模型: trained_models/model_*layers.pth")

print("\n" + "="*40)
print("🎉 单模式三波长测试成功完成!")
print("="*40)

# 可选:显示下一步建议
if 'performance_level' in locals():
    print(f"\n💡 基于当前结果的建议:")
    
    if performance_level == "优秀":
        print("  ✅ 系统性能优秀,可以考虑:")
        print("     - 增加更多波长进行测试")
        print("     - 尝试更复杂的模式配置")
        print("     - 优化系统参数以进一步提升性能")
    
    elif performance_level == "良好":
        print("  🔄 系统性能良好,建议优化:")
        print("     - 调整学习率和训练轮次")
        print("     - 优化层间距离和传播参数")
        print("     - 考虑使用不同的初始化策略")
    
    elif performance_level == "一般":
        print("  ⚠️ 系统性能一般,需要改进:")
        print("     - 增加训练轮次")
        print("     - 调整网络架构")
        print("     - 检查物理参数设置")
        print("     - 考虑使用预训练模型")
    
    else:
        print("  🔧 系统需要大幅改进:")
        print("     - 重新检查配置参数")
        print("     - 尝试不同的优化策略")
        print("     - 考虑简化问题复杂度")
        print("     - 检查数据生成和标签创建")

print(f"\nEND!")
============================================================
单模式三波长测试 - 基于多模式多波长框架
============================================================
测试配置:
  模式数: 1
  波长: ['450nm', '550nm', '650nm']
  训练轮次: 600
  保存目录: ./test_single_mode_tri_wavelength/

==================================================
阶段1: 数据准备
==================================================
创建数据生成器...
生成标签...
可视化标签布局...
/home/shiyue/ODNN/ODNN_WAVE/label_utils.py:179: UserWarning: Glyph 27169 (\N{CJK UNIFIED IDEOGRAPH-6A21}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/home/shiyue/ODNN/ODNN_WAVE/label_utils.py:179: UserWarning: Glyph 24335 (\N{CJK UNIFIED IDEOGRAPH-5F0F}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 27169 (\N{CJK UNIFIED IDEOGRAPH-6A21}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 24335 (\N{CJK UNIFIED IDEOGRAPH-5F0F}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
No description has been provided for this image
创建评估区域...
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 35780 (\N{CJK UNIFIED IDEOGRAPH-8BC4}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 20272 (\N{CJK UNIFIED IDEOGRAPH-4F30}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 21306 (\N{CJK UNIFIED IDEOGRAPH-533A}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 22495 (\N{CJK UNIFIED IDEOGRAPH-57DF}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 27874 (\N{CJK UNIFIED IDEOGRAPH-6CE2}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 38271 (\N{CJK UNIFIED IDEOGRAPH-957F}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 32452 (\N{CJK UNIFIED IDEOGRAPH-7EC4}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 21512 (\N{CJK UNIFIED IDEOGRAPH-5408}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
No description has been provided for this image
✓ 数据准备完成

==================================================
阶段2: 模型训练
==================================================
/home/shiyue/ODNN/ODNN_WAVE/light_propagation_simulation_qz.py:16: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).
  E = torch.tensor(E, dtype=torch.complex64, device=device)
开始训练新模型...
使用外部提供的评估区域: 9个区域

==================================================
开始训练 1 层模型...
==================================================
原始数据形状: (50, 50, 55)
选择后的数据形状: (1, 50, 50)
模式 1 振幅范围: 0.0 - 0.10288702696561813
计算波长系数 (基准波长: 550.0nm)
  波长 450.0nm: 系数 = 1.2222
  波长 550.0nm: 系数 = 1.0000
  波长 650.0nm: 系数 = 0.8462
开始训练 - 设备: cuda:0
训练参数: epochs=600, lr=0.01
Epoch [0/600], Loss: 0.002126811072230339
Epoch [100/600], Loss: 0.001940267276950181
Epoch [200/600], Loss: 0.001795723219402134
Epoch [300/600], Loss: 0.001751926029101014
Epoch [400/600], Loss: 0.001738202176056802
Epoch [500/600], Loss: 0.001733500976115465
✓ 训练完成!
计算可见度: 3波长, 1批次, 9区域, 1模式
处理波长 450nm (索引0)
  处理模式 1
    批次0: 能量=[np.float32(31.176598), np.float32(0.6715288), np.float32(0.4682008), np.float32(0.45753273), np.float32(0.470891), np.float32(0.48706293), np.float32(0.44744587), np.float32(0.48302454), np.float32(1.2478373)], 可见度=0.971702
  模式1平均可见度: 0.971702
处理波长 550nm (索引1)
  处理模式 1
    批次0: 能量=[np.float32(0.13249002), np.float32(1.0974427), np.float32(0.26266497), np.float32(0.45774895), np.float32(4.0975266), np.float32(0.3651052), np.float32(0.32847312), np.float32(0.3148498), np.float32(0.065190084)], 可见度=0.968679
  模式1平均可见度: 0.968679
处理波长 650nm (索引2)
  处理模式 1
    批次0: 能量=[np.float32(0.11418169), np.float32(0.13824184), np.float32(0.1938139), np.float32(0.35824522), np.float32(8.993116), np.float32(0.16057554), np.float32(0.30725354), np.float32(0.071792014), np.float32(0.052012097)], 可见度=0.988499
  模式1平均可见度: 0.988499
总共计算了 3 个可见度值
期望值: 3
✓ 完整模型已保存到: ./test_single_mode_tri_wavelength/trained_models/trained_model_1layers.pth
✓ 训练好的相位掩码已保存到: ./test_single_mode_tri_wavelength/trained_models/trained_phase_masks_1layers.npz
✓ 训练损失已保存到: ./test_single_mode_tri_wavelength/trained_models/training_losses_1layers.npy

====== 模型所有相位掩膜信息 ======

== 层 0 相位掩膜信息 ==
基础相位掩膜形状: (200, 200)
基础相位掩膜范围: [0.0000, 6.2806]
波长系数: [1.2222222  1.         0.84615386]
已保存层 0 的相位掩膜图像到 ./test_single_mode_tri_wavelength/trained_models/phase_mask_visualization_1layers/phase_mask_layer_0.png
✓ 1层模型训练完成,可见度数量: 3

==================================================
开始训练 2 层模型...
==================================================
计算波长系数 (基准波长: 550.0nm)
  波长 450.0nm: 系数 = 1.2222
  波长 550.0nm: 系数 = 1.0000
  波长 650.0nm: 系数 = 0.8462
计算波长系数 (基准波长: 550.0nm)
  波长 450.0nm: 系数 = 1.2222
  波长 550.0nm: 系数 = 1.0000
  波长 650.0nm: 系数 = 0.8462
开始训练 - 设备: cuda:0
训练参数: epochs=600, lr=0.01
Epoch [0/600], Loss: 0.002038316102698445
Epoch [100/600], Loss: 0.001521655824035406
Epoch [200/600], Loss: 0.001360742375254631
Epoch [300/600], Loss: 0.001308233127929270
Epoch [400/600], Loss: 0.001290174084715545
Epoch [500/600], Loss: 0.001283745281398296
✓ 训练完成!
计算可见度: 3波长, 1批次, 9区域, 1模式
处理波长 450nm (索引0)
  处理模式 1
    批次0: 能量=[np.float32(48.429134), np.float32(0.90361506), np.float32(0.26061636), np.float32(0.456967), np.float32(0.35262346), np.float32(0.33532256), np.float32(0.3854162), np.float32(0.49018598), np.float32(0.19210473)], 可见度=0.992098
  模式1平均可见度: 0.992098
处理波长 550nm (索引1)
  处理模式 1
    批次0: 能量=[np.float32(0.67694587), np.float32(19.28666), np.float32(0.48841017), np.float32(0.21392655), np.float32(0.842709), np.float32(0.34598875), np.float32(0.2511182), np.float32(0.21016824), np.float32(0.14864764)], 可见度=0.984703
  模式1平均可见度: 0.984703
处理波长 650nm (索引2)
  处理模式 1
    批次0: 能量=[np.float32(0.11994145), np.float32(1.274417), np.float32(4.2075343), np.float32(0.28013527), np.float32(3.0668652), np.float32(0.23336148), np.float32(0.15301588), np.float32(0.19845335), np.float32(0.19141558)], 可见度=0.944568
  模式1平均可见度: 0.944568
总共计算了 3 个可见度值
期望值: 3
✓ 完整模型已保存到: ./test_single_mode_tri_wavelength/trained_models/trained_model_2layers.pth
✓ 训练好的相位掩码已保存到: ./test_single_mode_tri_wavelength/trained_models/trained_phase_masks_2layers.npz
✓ 训练损失已保存到: ./test_single_mode_tri_wavelength/trained_models/training_losses_2layers.npy

====== 模型所有相位掩膜信息 ======

== 层 0 相位掩膜信息 ==
基础相位掩膜形状: (200, 200)
基础相位掩膜范围: [0.0001, 6.2804]
波长系数: [1.2222222  1.         0.84615386]
已保存层 0 的相位掩膜图像到 ./test_single_mode_tri_wavelength/trained_models/phase_mask_visualization_2layers/phase_mask_layer_0.png

== 层 1 相位掩膜信息 ==
基础相位掩膜形状: (200, 200)
基础相位掩膜范围: [0.0002, 6.2831]
波长系数: [1.2222222  1.         0.84615386]
已保存层 1 的相位掩膜图像到 ./test_single_mode_tri_wavelength/trained_models/phase_mask_visualization_2layers/phase_mask_layer_1.png
✓ 2层模型训练完成,可见度数量: 3

==================================================
开始训练 3 层模型...
==================================================
计算波长系数 (基准波长: 550.0nm)
  波长 450.0nm: 系数 = 1.2222
  波长 550.0nm: 系数 = 1.0000
  波长 650.0nm: 系数 = 0.8462
计算波长系数 (基准波长: 550.0nm)
  波长 450.0nm: 系数 = 1.2222
  波长 550.0nm: 系数 = 1.0000
  波长 650.0nm: 系数 = 0.8462
计算波长系数 (基准波长: 550.0nm)
  波长 450.0nm: 系数 = 1.2222
  波长 550.0nm: 系数 = 1.0000
  波长 650.0nm: 系数 = 0.8462
开始训练 - 设备: cuda:0
训练参数: epochs=600, lr=0.01
Epoch [0/600], Loss: 0.002031651092693210
Epoch [100/600], Loss: 0.001281421515159309
Epoch [200/600], Loss: 0.001048428588546813
Epoch [300/600], Loss: 0.000976397306658328
Epoch [400/600], Loss: 0.000952034490182996
Epoch [500/600], Loss: 0.000943399674724787
✓ 训练完成!
计算可见度: 3波长, 1批次, 9区域, 1模式
处理波长 450nm (索引0)
  处理模式 1
    批次0: 能量=[np.float32(51.452656), np.float32(0.600589), np.float32(0.4235201), np.float32(0.16258805), np.float32(0.23936549), np.float32(0.3157667), np.float32(0.20800397), np.float32(0.21829306), np.float32(0.24769947)], 可见度=0.993700
  模式1平均可见度: 0.993700
处理波长 550nm (索引1)
  处理模式 1
    批次0: 能量=[np.float32(0.48631373), np.float32(33.02899), np.float32(0.5151269), np.float32(0.28017265), np.float32(0.54638475), np.float32(0.17614119), np.float32(0.17727137), np.float32(0.27920362), np.float32(0.3592738)], 可见度=0.989391
  模式1平均可见度: 0.989391
处理波长 650nm (索引2)
  处理模式 1
    批次0: 能量=[np.float32(0.4219358), np.float32(0.5842478), np.float32(15.725937), np.float32(0.16864428), np.float32(1.3198507), np.float32(0.1327889), np.float32(0.34667677), np.float32(0.1892734), np.float32(0.2034376)], 可见度=0.983254
  模式1平均可见度: 0.983254
总共计算了 3 个可见度值
期望值: 3
✓ 完整模型已保存到: ./test_single_mode_tri_wavelength/trained_models/trained_model_3layers.pth
✓ 训练好的相位掩码已保存到: ./test_single_mode_tri_wavelength/trained_models/trained_phase_masks_3layers.npz
✓ 训练损失已保存到: ./test_single_mode_tri_wavelength/trained_models/training_losses_3layers.npy

====== 模型所有相位掩膜信息 ======

== 层 0 相位掩膜信息 ==
基础相位掩膜形状: (200, 200)
基础相位掩膜范围: [0.0001, 6.2808]
波长系数: [1.2222222  1.         0.84615386]
已保存层 0 的相位掩膜图像到 ./test_single_mode_tri_wavelength/trained_models/phase_mask_visualization_3layers/phase_mask_layer_0.png

== 层 1 相位掩膜信息 ==
基础相位掩膜形状: (200, 200)
基础相位掩膜范围: [0.0001, 6.2806]
波长系数: [1.2222222  1.         0.84615386]
已保存层 1 的相位掩膜图像到 ./test_single_mode_tri_wavelength/trained_models/phase_mask_visualization_3layers/phase_mask_layer_1.png

== 层 2 相位掩膜信息 ==
基础相位掩膜形状: (200, 200)
基础相位掩膜范围: [0.0005, 6.2829]
波长系数: [1.2222222  1.         0.84615386]
已保存层 2 的相位掩膜图像到 ./test_single_mode_tri_wavelength/trained_models/phase_mask_visualization_3layers/phase_mask_layer_2.png
✓ 3层模型训练完成,可见度数量: 3
✓ 模型准备完成

==================================================
阶段3: 结果分析
==================================================
检查训练结果...
results键: ['models', 'losses', 'phase_masks', 'weights_pred', 'visibility']
可见度数据结构: 3层
第1层 (1层模型):
  数据长度: 3
  期望长度: 3 (3波长 × 1模式)
  ✅ 数据长度匹配!
    450nm: 模式1=0.971702
    550nm: 模式1=0.968679
    650nm: 模式1=0.988499
第2层 (2层模型):
  数据长度: 3
  期望长度: 3 (3波长 × 1模式)
  ✅ 数据长度匹配!
    450nm: 模式1=0.992098
    550nm: 模式1=0.984703
    650nm: 模式1=0.944568
第3层 (3层模型):
  数据长度: 3
  期望长度: 3 (3波长 × 1模式)
  ✅ 数据长度匹配!
    450nm: 模式1=0.993700
    550nm: 模式1=0.989391
    650nm: 模式1=0.983254
可视化训练损失...
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 25439 (\N{CJK UNIFIED IDEOGRAPH-635F}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 22833 (\N{CJK UNIFIED IDEOGRAPH-5931}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 20540 (\N{CJK UNIFIED IDEOGRAPH-503C}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 21333 (\N{CJK UNIFIED IDEOGRAPH-5355}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 27169 (\N{CJK UNIFIED IDEOGRAPH-6A21}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 24335 (\N{CJK UNIFIED IDEOGRAPH-5F0F}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 27874 (\N{CJK UNIFIED IDEOGRAPH-6CE2}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 38271 (\N{CJK UNIFIED IDEOGRAPH-957F}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 19981 (\N{CJK UNIFIED IDEOGRAPH-4E0D}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 21516 (\N{CJK UNIFIED IDEOGRAPH-540C}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 23618 (\N{CJK UNIFIED IDEOGRAPH-5C42}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 25968 (\N{CJK UNIFIED IDEOGRAPH-6570}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 22411 (\N{CJK UNIFIED IDEOGRAPH-578B}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 30340 (\N{CJK UNIFIED IDEOGRAPH-7684}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 35757 (\N{CJK UNIFIED IDEOGRAPH-8BAD}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 32451 (\N{CJK UNIFIED IDEOGRAPH-7EC3}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 36718 (\N{CJK UNIFIED IDEOGRAPH-8F6E}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:297: UserWarning: Glyph 27425 (\N{CJK UNIFIED IDEOGRAPH-6B21}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/training_losses.png", dpi=300)
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 25439 (\N{CJK UNIFIED IDEOGRAPH-635F}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 22833 (\N{CJK UNIFIED IDEOGRAPH-5931}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 20540 (\N{CJK UNIFIED IDEOGRAPH-503C}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 21333 (\N{CJK UNIFIED IDEOGRAPH-5355}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 19981 (\N{CJK UNIFIED IDEOGRAPH-4E0D}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 21516 (\N{CJK UNIFIED IDEOGRAPH-540C}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 23618 (\N{CJK UNIFIED IDEOGRAPH-5C42}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 25968 (\N{CJK UNIFIED IDEOGRAPH-6570}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 22411 (\N{CJK UNIFIED IDEOGRAPH-578B}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 30340 (\N{CJK UNIFIED IDEOGRAPH-7684}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 35757 (\N{CJK UNIFIED IDEOGRAPH-8BAD}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 32451 (\N{CJK UNIFIED IDEOGRAPH-7EC3}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 36718 (\N{CJK UNIFIED IDEOGRAPH-8F6E}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 27425 (\N{CJK UNIFIED IDEOGRAPH-6B21}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
No description has been provided for this image
/tmp/ipykernel_9963/2537366200.py:335: UserWarning: Glyph 23618 (\N{CJK UNIFIED IDEOGRAPH-5C42}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:335: UserWarning: Glyph 25968 (\N{CJK UNIFIED IDEOGRAPH-6570}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:335: UserWarning: Glyph 21487 (\N{CJK UNIFIED IDEOGRAPH-53EF}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:335: UserWarning: Glyph 35265 (\N{CJK UNIFIED IDEOGRAPH-89C1}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:335: UserWarning: Glyph 24230 (\N{CJK UNIFIED IDEOGRAPH-5EA6}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:335: UserWarning: Glyph 21333 (\N{CJK UNIFIED IDEOGRAPH-5355}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:335: UserWarning: Glyph 27169 (\N{CJK UNIFIED IDEOGRAPH-6A21}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:335: UserWarning: Glyph 24335 (\N{CJK UNIFIED IDEOGRAPH-5F0F}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:335: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:335: UserWarning: Glyph 27874 (\N{CJK UNIFIED IDEOGRAPH-6CE2}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:335: UserWarning: Glyph 38271 (\N{CJK UNIFIED IDEOGRAPH-957F}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:335: UserWarning: Glyph 23545 (\N{CJK UNIFIED IDEOGRAPH-5BF9}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:335: UserWarning: Glyph 27604 (\N{CJK UNIFIED IDEOGRAPH-6BD4}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:336: UserWarning: Glyph 21487 (\N{CJK UNIFIED IDEOGRAPH-53EF}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:336: UserWarning: Glyph 35265 (\N{CJK UNIFIED IDEOGRAPH-89C1}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:336: UserWarning: Glyph 24230 (\N{CJK UNIFIED IDEOGRAPH-5EA6}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:336: UserWarning: Glyph 23618 (\N{CJK UNIFIED IDEOGRAPH-5C42}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:336: UserWarning: Glyph 25968 (\N{CJK UNIFIED IDEOGRAPH-6570}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:336: UserWarning: Glyph 21333 (\N{CJK UNIFIED IDEOGRAPH-5355}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:336: UserWarning: Glyph 27169 (\N{CJK UNIFIED IDEOGRAPH-6A21}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:336: UserWarning: Glyph 24335 (\N{CJK UNIFIED IDEOGRAPH-5F0F}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
可视化三波长可见度结果...
/tmp/ipykernel_9963/2537366200.py:336: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:336: UserWarning: Glyph 27874 (\N{CJK UNIFIED IDEOGRAPH-6CE2}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:336: UserWarning: Glyph 38271 (\N{CJK UNIFIED IDEOGRAPH-957F}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:336: UserWarning: Glyph 23545 (\N{CJK UNIFIED IDEOGRAPH-5BF9}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:336: UserWarning: Glyph 27604 (\N{CJK UNIFIED IDEOGRAPH-6BD4}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_visibility.png", dpi=300)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 21487 (\N{CJK UNIFIED IDEOGRAPH-53EF}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 35265 (\N{CJK UNIFIED IDEOGRAPH-89C1}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 24230 (\N{CJK UNIFIED IDEOGRAPH-5EA6}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 23545 (\N{CJK UNIFIED IDEOGRAPH-5BF9}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 27604 (\N{CJK UNIFIED IDEOGRAPH-6BD4}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
No description has been provided for this image
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 23618 (\N{CJK UNIFIED IDEOGRAPH-5C42}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 25968 (\N{CJK UNIFIED IDEOGRAPH-6570}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 21487 (\N{CJK UNIFIED IDEOGRAPH-53EF}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 35265 (\N{CJK UNIFIED IDEOGRAPH-89C1}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 24230 (\N{CJK UNIFIED IDEOGRAPH-5EA6}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 27874 (\N{CJK UNIFIED IDEOGRAPH-6CE2}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 38271 (\N{CJK UNIFIED IDEOGRAPH-957F}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 38543 (\N{CJK UNIFIED IDEOGRAPH-968F}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 21464 (\N{CJK UNIFIED IDEOGRAPH-53D8}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 21270 (\N{CJK UNIFIED IDEOGRAPH-5316}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 27169 (\N{CJK UNIFIED IDEOGRAPH-6A21}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 22411 (\N{CJK UNIFIED IDEOGRAPH-578B}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 19981 (\N{CJK UNIFIED IDEOGRAPH-4E0D}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 21516 (\N{CJK UNIFIED IDEOGRAPH-540C}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 30340 (\N{CJK UNIFIED IDEOGRAPH-7684}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 23545 (\N{CJK UNIFIED IDEOGRAPH-5BF9}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:397: UserWarning: Glyph 27604 (\N{CJK UNIFIED IDEOGRAPH-6BD4}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 21487 (\N{CJK UNIFIED IDEOGRAPH-53EF}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 35265 (\N{CJK UNIFIED IDEOGRAPH-89C1}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 24230 (\N{CJK UNIFIED IDEOGRAPH-5EA6}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 27874 (\N{CJK UNIFIED IDEOGRAPH-6CE2}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 38271 (\N{CJK UNIFIED IDEOGRAPH-957F}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 38543 (\N{CJK UNIFIED IDEOGRAPH-968F}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 23618 (\N{CJK UNIFIED IDEOGRAPH-5C42}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 25968 (\N{CJK UNIFIED IDEOGRAPH-6570}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 21464 (\N{CJK UNIFIED IDEOGRAPH-53D8}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 21270 (\N{CJK UNIFIED IDEOGRAPH-5316}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 19981 (\N{CJK UNIFIED IDEOGRAPH-4E0D}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 21516 (\N{CJK UNIFIED IDEOGRAPH-540C}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 27169 (\N{CJK UNIFIED IDEOGRAPH-6A21}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
创建三波长综合对比图...
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 22411 (\N{CJK UNIFIED IDEOGRAPH-578B}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 30340 (\N{CJK UNIFIED IDEOGRAPH-7684}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 23545 (\N{CJK UNIFIED IDEOGRAPH-5BF9}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/tmp/ipykernel_9963/2537366200.py:398: UserWarning: Glyph 27604 (\N{CJK UNIFIED IDEOGRAPH-6BD4}) missing from font(s) DejaVu Sans.
  plt.savefig(f"{config.save_dir}/tri_wavelength_comprehensive.png", dpi=300)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 21487 (\N{CJK UNIFIED IDEOGRAPH-53EF}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 35265 (\N{CJK UNIFIED IDEOGRAPH-89C1}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 24230 (\N{CJK UNIFIED IDEOGRAPH-5EA6}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 27874 (\N{CJK UNIFIED IDEOGRAPH-6CE2}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 38271 (\N{CJK UNIFIED IDEOGRAPH-957F}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 38543 (\N{CJK UNIFIED IDEOGRAPH-968F}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 23618 (\N{CJK UNIFIED IDEOGRAPH-5C42}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 25968 (\N{CJK UNIFIED IDEOGRAPH-6570}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 21464 (\N{CJK UNIFIED IDEOGRAPH-53D8}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 21270 (\N{CJK UNIFIED IDEOGRAPH-5316}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 19981 (\N{CJK UNIFIED IDEOGRAPH-4E0D}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 21516 (\N{CJK UNIFIED IDEOGRAPH-540C}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 27169 (\N{CJK UNIFIED IDEOGRAPH-6A21}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 22411 (\N{CJK UNIFIED IDEOGRAPH-578B}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 30340 (\N{CJK UNIFIED IDEOGRAPH-7684}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 23545 (\N{CJK UNIFIED IDEOGRAPH-5BF9}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
/home/shiyue/miniconda3/envs/ODNN/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 27604 (\N{CJK UNIFIED IDEOGRAPH-6BD4}) missing from font(s) DejaVu Sans.
  fig.canvas.print_figure(bytes_io, **kw)
No description has been provided for this image
创建详细可视化分析...
按模式组织可见度数据...
配置: 1模式, 3波长, 3层数
原始数据结构: [3, 3, 3]
检测到: 完整多波长数据
图表已保存至: ./test_single_mode_tri_wavelength//visibility_by_mode.png
No description has been provided for this image
图表已保存至: ./test_single_mode_tri_wavelength//visibility_matrix.png
No description has been provided for this image
=== 可见度数据摘要 ===

模式 1:
层数	450nm	550nm	650nm
--------------------------------
1	0.972	0.969	0.988
2	0.992	0.985	0.945
3	0.994	0.989	0.983

=== 平均可见度(跨所有层数和波长)===
模式 1: 0.980
可见度数据已保存至: ./test_single_mode_tri_wavelength//visibility_data.csv
✓ 结果分析完成

==================================================
阶段4: 光场传播仿真(所有模型)
==================================================
获取所有有效模型...
发现 3 个有效模型,将分别进行传播仿真
准备仿真掩码...
生成输入场...

--- 处理第 1/3 个模型: 1层 ---
平均可见度: 0.9763
  450nm: 0.9717
  550nm: 0.9687
  650nm: 0.9885
✓ 使用训练好的相位掩码进行仿真
创建 1 层模型的模拟器...
为 1 层模型生成专用相位掩膜...
为模式 1 生成专用掩膜...
模拟 1 层模型的光场传播...
输入字段维度: 4D, 形状: torch.Size([1, 3, 50, 50])
检测到4D输入 [mode, wavelength, height, width],共1个模式

处理模式 1/1
  使用模式 1 的专用相位掩膜
输入字段维度: 3D, 形状: torch.Size([3, 50, 50])
  λ = 450 nm
/home/shiyue/ODNN/ODNN_WAVE/light_propagation_simulation_qz.py:16: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).
  E = torch.tensor(E, dtype=torch.complex64, device=device)
No description has been provided for this image
  → 结束

  聚焦质量_mode1:
    质心位置: (80.5, 82.6)
    峰值位置: (np.int64(47), np.int64(47))
    聚焦比例: 1.0000
    峰值强度: 0.609839
✅ Data saved: ./test_single_mode_tri_wavelength/MC_single_450nm_mode1_M1_1layers_TestSim_0.0000_20250814_0925.npy (替代 .mat 格式)
  λ = 550 nm
No description has been provided for this image
  → 结束

  聚焦质量_mode1:
    质心位置: (83.8, 87.2)
    峰值位置: (np.int64(35), np.int64(35))
    聚焦比例: 1.0000
    峰值强度: 0.219748
✅ Data saved: ./test_single_mode_tri_wavelength/MC_single_550nm_mode1_M1_1layers_TestSim_0.0000_20250814_0925.npy (替代 .mat 格式)
  λ = 650 nm
No description has been provided for this image
  → 结束

  聚焦质量_mode1:
    质心位置: (85.7, 88.4)
    峰值位置: (np.int64(99), np.int64(100))
    聚焦比例: 1.0000
    峰值强度: 0.094563
✅ Data saved: ./test_single_mode_tri_wavelength/MC_single_650nm_mode1_M1_1layers_TestSim_0.0000_20250814_0925.npy (替代 .mat 格式)

评估传播结果:
模式0波长0: 最大能量在区域4 (模式1,波长1), 正确: False
保存 1 层模型的相位掩膜信息...

====== 模型所有相位掩膜信息 ======

== 层 0 相位掩膜信息 ==
基础相位掩膜形状: (200, 200)
基础相位掩膜范围: [0.0000, 6.2806]
波长系数: [1.2222222  1.         0.84615386]
已保存层 0 的相位掩膜图像到 ./test_single_mode_tri_wavelength/1layer_model/phase_mask_layer_0.png
✓ 1 层模型仿真完成

--- 处理第 2/3 个模型: 2层 ---
平均可见度: 0.9738
  450nm: 0.9921
  550nm: 0.9847
  650nm: 0.9446
✓ 使用训练好的相位掩码进行仿真
创建 2 层模型的模拟器...
为 2 层模型生成专用相位掩膜...
为模式 1 生成专用掩膜...
模拟 2 层模型的光场传播...
输入字段维度: 4D, 形状: torch.Size([1, 3, 50, 50])
检测到4D输入 [mode, wavelength, height, width],共1个模式

处理模式 1/1
  使用模式 1 的专用相位掩膜
输入字段维度: 3D, 形状: torch.Size([3, 50, 50])
  λ = 450 nm
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
  → 结束

  聚焦质量_mode1:
    质心位置: (70.4, 72.9)
    峰值位置: (np.int64(47), np.int64(47))
    聚焦比例: 1.0000
    峰值强度: 1.208502
✅ Data saved: ./test_single_mode_tri_wavelength/MC_single_450nm_mode1_M1_2layers_TestSim_0.0000_20250814_0925.npy (替代 .mat 格式)
  λ = 550 nm
No description has been provided for this image
No description has been provided for this image
  → 结束

  聚焦质量_mode1:
    质心位置: (84.5, 96.7)
    峰值位置: (np.int64(47), np.int64(101))
    聚焦比例: 1.0000
    峰值强度: 0.407679
✅ Data saved: ./test_single_mode_tri_wavelength/MC_single_550nm_mode1_M1_2layers_TestSim_0.0000_20250814_0925.npy (替代 .mat 格式)
  λ = 650 nm
No description has been provided for this image
No description has been provided for this image
  → 结束

  聚焦质量_mode1:
    质心位置: (90.1, 100.3)
    峰值位置: (np.int64(48), np.int64(153))
    聚焦比例: 1.0000
    峰值强度: 0.107301
✅ Data saved: ./test_single_mode_tri_wavelength/MC_single_650nm_mode1_M1_2layers_TestSim_0.0000_20250814_0925.npy (替代 .mat 格式)

评估传播结果:
模式0波长0: 最大能量在区域4 (模式1,波长1), 正确: False
保存 2 层模型的相位掩膜信息...

====== 模型所有相位掩膜信息 ======

== 层 0 相位掩膜信息 ==
基础相位掩膜形状: (200, 200)
基础相位掩膜范围: [0.0001, 6.2804]
波长系数: [1.2222222  1.         0.84615386]
已保存层 0 的相位掩膜图像到 ./test_single_mode_tri_wavelength/2layer_model/phase_mask_layer_0.png

== 层 1 相位掩膜信息 ==
基础相位掩膜形状: (200, 200)
基础相位掩膜范围: [0.0002, 6.2831]
波长系数: [1.2222222  1.         0.84615386]
已保存层 1 的相位掩膜图像到 ./test_single_mode_tri_wavelength/2layer_model/phase_mask_layer_1.png
✓ 2 层模型仿真完成

--- 处理第 3/3 个模型: 3层 ---
平均可见度: 0.9888
  450nm: 0.9937
  550nm: 0.9894
  650nm: 0.9833
✓ 使用训练好的相位掩码进行仿真
创建 3 层模型的模拟器...
为 3 层模型生成专用相位掩膜...
为模式 1 生成专用掩膜...
模拟 3 层模型的光场传播...
输入字段维度: 4D, 形状: torch.Size([1, 3, 50, 50])
检测到4D输入 [mode, wavelength, height, width],共1个模式

处理模式 1/1
  使用模式 1 的专用相位掩膜
输入字段维度: 3D, 形状: torch.Size([3, 50, 50])
  λ = 450 nm
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
  → 结束

  聚焦质量_mode1:
    质心位置: (74.0, 76.7)
    峰值位置: (np.int64(48), np.int64(48))
    聚焦比例: 1.0000
    峰值强度: 0.992810
✅ Data saved: ./test_single_mode_tri_wavelength/MC_single_450nm_mode1_M1_3layers_TestSim_0.0000_20250814_0925.npy (替代 .mat 格式)
  λ = 550 nm
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
  → 结束

  聚焦质量_mode1:
    质心位置: (79.0, 100.9)
    峰值位置: (np.int64(47), np.int64(99))
    聚焦比例: 1.0000
    峰值强度: 0.782995
✅ Data saved: ./test_single_mode_tri_wavelength/MC_single_550nm_mode1_M1_3layers_TestSim_0.0000_20250814_0925.npy (替代 .mat 格式)
  λ = 650 nm
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
  → 结束

  聚焦质量_mode1:
    质心位置: (85.7, 106.5)
    峰值位置: (np.int64(48), np.int64(153))
    聚焦比例: 1.0000
    峰值强度: 0.280980
✅ Data saved: ./test_single_mode_tri_wavelength/MC_single_650nm_mode1_M1_3layers_TestSim_0.0000_20250814_0925.npy (替代 .mat 格式)

评估传播结果:
模式0波长0: 最大能量在区域2 (模式0,波长2), 正确: False
保存 3 层模型的相位掩膜信息...

====== 模型所有相位掩膜信息 ======

== 层 0 相位掩膜信息 ==
基础相位掩膜形状: (200, 200)
基础相位掩膜范围: [0.0001, 6.2808]
波长系数: [1.2222222  1.         0.84615386]
已保存层 0 的相位掩膜图像到 ./test_single_mode_tri_wavelength/3layer_model/phase_mask_layer_0.png

== 层 1 相位掩膜信息 ==
基础相位掩膜形状: (200, 200)
基础相位掩膜范围: [0.0001, 6.2806]
波长系数: [1.2222222  1.         0.84615386]
已保存层 1 的相位掩膜图像到 ./test_single_mode_tri_wavelength/3layer_model/phase_mask_layer_1.png

== 层 2 相位掩膜信息 ==
基础相位掩膜形状: (200, 200)
基础相位掩膜范围: [0.0005, 6.2829]
波长系数: [1.2222222  1.         0.84615386]
已保存层 2 的相位掩膜图像到 ./test_single_mode_tri_wavelength/3layer_model/phase_mask_layer_2.png
✓ 3 层模型仿真完成

--- 所有模型仿真结果总结 ---
模型性能对比:
  1层模型: 平均可见度 = 0.9763
    450nm: 0.9717
    550nm: 0.9687
    650nm: 0.9885
  2层模型: 平均可见度 = 0.9738
    450nm: 0.9921
    550nm: 0.9847
    650nm: 0.9446
  3层模型: 平均可见度 = 0.9888
    450nm: 0.9937
    550nm: 0.9894
    650nm: 0.9833

🏆 最佳模型: 3层
   平均可见度: 0.9888
   450nm: 0.9937
   550nm: 0.9894
   650nm: 0.9833

📊 三波长性能分析:
   最高可见度: 0.9937 (450nm)
   最低可见度: 0.9833 (650nm)
   标准差: 0.0043
   平衡度: 0.9957 (越接近1越平衡)

✅ 所有 3 个模型的仿真完成
✓ 光场传播仿真阶段完成

==================================================
阶段5: 保存最终结果
==================================================
保存完整结果...
✓ 主结果已保存: ./test_single_mode_tri_wavelength//complete_results_20250814_0925.pth
✓ 1层模型已保存: ./test_single_mode_tri_wavelength/trained_models/model_1layers.pth
✓ 2层模型已保存: ./test_single_mode_tri_wavelength/trained_models/model_2layers.pth
✓ 3层模型已保存: ./test_single_mode_tri_wavelength/trained_models/model_3layers.pth
生成三波长性能分析报告...
✓ 三波长分析报告已保存: ./test_single_mode_tri_wavelength//tri_wavelength_analysis_report.txt
✓ 所有结果保存完成

============================================================
单模式三波长测试完成!
============================================================
总执行时间: 116.81 秒 (1.95 分钟)

=== 测试执行摘要 ===
测试类型: 单模式三波长
模式数: 1
波长: ['450nm', '550nm', '650nm']
训练层数选项: [1, 2, 3]
训练轮次: 600
保存目录: ./test_single_mode_tri_wavelength/

🏆 最佳模型: 3层
平均可见度: 0.9888
各波长性能:
  450nm: 0.9937
  550nm: 0.9894
  650nm: 0.9833

📊 三波长平衡性:
  标准差: 0.0043
  平衡度评分: 0.9957 (0-1,越高越平衡)
  综合性能等级: 优秀

📁 主要输出文件:
  完整结果: complete_results_20250814_0925.pth
  分析报告: tri_wavelength_analysis_report.txt
  可视化图表: tri_wavelength_*.png
  训练模型: trained_models/model_*layers.pth

========================================
🎉 单模式三波长测试成功完成!
========================================

💡 基于当前结果的建议:
  ✅ 系统性能优秀,可以考虑:
     - 增加更多波长进行测试
     - 尝试更复杂的模式配置
     - 优化系统参数以进一步提升性能

END!
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image